home *** CD-ROM | disk | FTP | other *** search
/ NetNews Offline 2 / NetNews Offline Volume 2.iso / news / comp / lang / c++-part1 / 2423 < prev    next >
Encoding:
Text File  |  1996-08-06  |  4.3 KB  |  147 lines

  1. Path: news.ccs.queensu.ca!news
  2. From: Wintermute <3mal5@qlink.queensu.ca>
  3. Newsgroups: comp.lang.c++
  4. Subject: Re: Callbacks using member functions
  5. Date: 17 Jan 1996 18:35:14 GMT
  6. Organization: System Infinity
  7. Message-ID: <4djfh2$1oo@knot.queensu.ca>
  8. References: <4dheva$rjl@news1.usa.pipeline.com>
  9. NNTP-Posting-Host: free2-slip218.tele.queensu.ca
  10. Mime-Version: 1.0
  11. Content-Type: text/plain; charset=us-ascii
  12. Content-Transfer-Encoding: 7bit
  13. X-Mailer: Mozilla 1.1N (Macintosh; I; 68K)
  14. X-URL: news:4dheva$rjl@news1.usa.pipeline.com
  15.  
  16. I received the following email reply from one Rick Whitehouse (who could 
  17. not get his Netscape to post it).  It seems to be what I am looking for, 
  18. and it seems like it will work (will try it in next few days).
  19.  
  20. [begin insertion]
  21.  
  22.     I had the same problem you are.  We are writing Motif applications in
  23. C++ and use member functions as call-backs.  You are correct about the 
  24. 'this'
  25. pointer messing things up.  The call-back expects the widget pointer to 
  26. be
  27. first, but the compiler sends the 'this' pointer first.  The solution is 
  28. to
  29. declare the member functions as static.  If you remember from the LRM, 
  30. when you
  31. declare a member function as static, it loses it's intrinsic membership
  32. attributes: i.e. you have to explicitly send the object pointer and used 
  33. the
  34. qualified notation when you call it.  This is perfect for callback 
  35. purposes!!
  36.  
  37.     Here is what you need to do to complete the entire implementation:
  38.  
  39.     1)  Declare the member functions as static in the class declaration.
  40.     2)  Declare the functions in the normal C manner.
  41.     3)  Provide the implementation the same as any other member function.
  42.  
  43.     An example will clear this up.
  44.  
  45.     In the class' public header file, MyClass.hh:
  46.  
  47. class MyClass
  48. {
  49.     public    :
  50.  
  51.         MyClass ();
  52.  
  53.         ~MyClass ();
  54.  
  55.     private    :
  56.  
  57.         static void MyCallback (Widget    w,
  58.                                 XtPointer clientData,
  59.                                 XtPointer callData);
  60. };
  61.  
  62.     Since all of the code will be defined in the context of the class, 
  63. these
  64. member functions can be public, protected or private.  I choose private 
  65. because
  66. of the way I structure my classes and applications.
  67.  
  68.     A *private* header file comes in handy.  This is like the private 
  69. header
  70. files used with the widgets themselves.  In this private header file,
  71. MyClassP.hh:
  72.  
  73. #include "MyClass.hh"
  74.  
  75. void MyCallback (Widget    w,
  76.                  XtPointer clientData,
  77.                  XtPointer callData);
  78.  
  79.     Then, in the implementation file, the implementation of the callback is
  80. like any other member function (MyClass.cc):
  81.  
  82. #include "MyClassP.hh"
  83.  
  84. MyClass::MyClass ()
  85. {
  86. }
  87.  
  88. MyClass::~MyClass()
  89. {
  90. }
  91.  
  92. MyClass::MyCallback (Widget    w,
  93.                      XtPointer clientData,
  94.                      XtPointer callData)
  95. {
  96. }
  97.  
  98.     Now, remember I said that a static member function loses some of its
  99. membership attributes?  Here is where not having the 'this' pointer is a 
  100. bless-
  101. ing and a curse.  Usually, you would want to do something useful in the 
  102. object,
  103. otherwise you wouldn't be putting the call-back in the class in the 
  104. first place.
  105. When you add the call-back to the appropriate widget's callback list, 
  106. you need
  107. to supply the 'this' pointer.  This is most easily done in the class'
  108. constructor and use the 'this' pointer as your clientData parameter:
  109.  
  110.     XtAddCallback (w, XmNdestroyCallback, MyCallback, (XtPointer)this);
  111.  
  112.     Then, in your call-back, you get to you object like this:
  113.  
  114. MyClass::MyCallback (Widget    w,
  115.                      XtPointer clientData,
  116.                      XtPointer callData)
  117. {
  118. MyClass *myClass= (MyClass *)clientData;
  119.     .
  120.     .
  121.     .
  122. }
  123.  
  124.     You can get around the automatic variable and the type-cast by 
  125. declaring
  126. the second parameter to your call-back as a pointer to the object from 
  127. the start
  128. and then use it directly in your call-back.
  129.  
  130.     Please let me know if this helps or not, and just the fact that you got
  131. this message (since I am having trouble with Netscape).  Good luck!!
  132.  
  133.                 Rick Whitehouse
  134.  
  135. [end insertion]
  136.  
  137. Mostly, I realize C++ doesn't fit flawlessly with MOTIF, but like having 
  138. everything wrapped up in its own class; just my preferred design style.
  139.  
  140. --
  141. Wintermute  <3mal5@qlink.queensu.ca>  <http://qlink.queensu.ca/~3mal5/>
  142.  
  143. "If I really knew how to write, I could write something that someone
  144. could read and it would kill them."  -  william s. burroughs
  145.  
  146.  
  147.